﻿using System;
using System.IO;
using System.Linq;
using DevelopTool.Common;
using DevelopTool.Model.ChatModels;
using DevelopTool.Model.Enums;
using Nancy;
using Nancy.Extensions;

namespace DevelopTool.Bll.ChatBlls
{
    public class ChatModule : NancyModule
    {
        private ChatBll chatBll;


        public ChatModule()
        {
            chatBll = new ChatBll();


            //接收文本消息
            Post["/TextMessage"] = p =>
            {
                ChatMessageReceiveResult receiveResult = new ChatMessageReceiveResult();

                try
                {
                    receiveResult.SendIp = Request.UserHostAddress;

                    string json = Request.Body.AsString();

                    chatBll.ReceiveTextMessage(json);

                    receiveResult.ReceiveState = ChatMessageSendState.Success;
                    receiveResult.Message = "ok";
                                        
                }
                catch (Exception ex)
                {
                    LogHelper.WriteErrLog(ex, false);

                    receiveResult.ReceiveState = ChatMessageSendState.ReceiveError;
                    receiveResult.Message = ex.Message;
                }

                return receiveResult.SerializeObject().EncryptAndCompress();
            };


            //接收文件元数据
            Post["/FileMetaData"] = p =>
            {
                ChatMessageReceiveResult receiveResult = new ChatMessageReceiveResult();

                try
                {
                    receiveResult.SendIp = Request.UserHostAddress;

                    string json = Request.Body.AsString();

                    chatBll.ReceiveFileMetaData(json);

                    receiveResult.ReceiveState = ChatMessageSendState.Success;
                    receiveResult.Message = "ok";
                    
                }
                catch (Exception ex)
                {
                    LogHelper.WriteErrLog(ex, false);

                    receiveResult.ReceiveState = ChatMessageSendState.ReceiveError;
                    receiveResult.Message = ex.Message;
                }

                return receiveResult.SerializeObject().EncryptAndCompress();
            };


            //接收文件分片数据
            Post["/FileChunkData"] = p =>
            {
                ChatMessageReceiveResult receiveResult = new ChatMessageReceiveResult();

                try
                {
                    receiveResult.SendIp = Request.UserHostAddress;

                    string json = Request.Body.AsString();

                    // 解析文件分片数据
                    ChatFileChunkData chatFileChunkData = json.DecryptAndDecompress().DeserializeObject<ChatFileChunkData>();

                    // 分片文件临时目录
                    string chunkDir = Path.Combine(GlobalData.AppTempDirectory, "FileChunkData", chatFileChunkData.FileId);

                    DirectoryInfo chunkDirInfo = new DirectoryInfo(chunkDir);
                    if (!chunkDirInfo.Exists) chunkDirInfo.Create(); // 如果分片文件临时目录不存在则创建

                    // 分片文件路径
                    string chunkFilePath = Path.Combine(chunkDir, chatFileChunkData.ChunkIndex.ToString() + ".chunk");
                    if (File.Exists(chunkFilePath))
                    {
                        receiveResult.ReceiveState = ChatMessageSendState.Success;
                        receiveResult.Message = "exists";
                        return receiveResult;
                    }

                    // 写入分片文件
                    File.WriteAllBytes(chunkFilePath, chatFileChunkData.Data);

                    // 所有分片接收完成
                    if (chunkDirInfo.EnumerateFiles("*.chunk").Count() == chatFileChunkData.TotalChunks)
                    {
                        //目标目录路径
                        string targetDirectory = Path.Combine(Setting.Chat.BinarySavePath, chatFileChunkData.UserId);
                        Directory.CreateDirectory(targetDirectory);

                        // 目标文件路径,确保目标文件不会因为之前的残留数据而出错  
                        string targetFile = Path.Combine(targetDirectory, FileHelper.GenerateUniqueFileName(chatFileChunkData.FileName, targetDirectory));

                        using (var targetFileStream = File.Create(targetFile))
                        {
                            var allChunkFiles = chunkDirInfo.EnumerateFiles("*.chunk").OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f.Name))).ToList();

                            foreach (var chunkFile in allChunkFiles)
                            {
                                using (var stream = chunkFile.OpenRead())
                                {
                                    stream.CopyTo(targetFileStream); // 复制分片文件内容到目标文件流
                                }
                            }

                            // 删除临时目录和临时分片文件
                            foreach (var chunkFile in allChunkFiles)
                            {
                                chunkFile.Delete();
                            }
                            chunkDirInfo.Delete(true);
                        }

                        chatBll.ReceiveFileChunkData(chatFileChunkData, targetFile);
                    }
                    else
                    {
                        chatBll.ReceiveFileChunkData(chatFileChunkData, string.Empty);
                    }


                    receiveResult.ReceiveState = ChatMessageSendState.Success;
                    receiveResult.Message = "ok";
                }
                catch (Exception ex)
                {
                    LogHelper.WriteErrLog(ex, false);

                    receiveResult.ReceiveState = ChatMessageSendState.ReceiveError;
                    receiveResult.Message = ex.Message;
                }

                return receiveResult.SerializeObject().EncryptAndCompress();
            };


        }


    }
}
